package flightlifter;

import java.util.Vector;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector3f;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Matt
 */
public class Point extends Node {

    PVector pos;
    PVector lastPos;
    PVector tempPos;
    PVector accel;
    float mass = 1.f; //in Kg
    float elasticity = .5f;
    int count = 0;

    public Point() {
        pos = new PVector(0.f, 15.f, 0.f);
        lastPos = new PVector(0, 15.f, 0.f);
        tempPos = new PVector(0.f, 15.f, 0.f);
        accel = new PVector(0, 0, 0);
    }

    public Point(float x, float y, float z) {

        pos = new PVector(x, y, z);
        lastPos = new PVector(x, y, z);
        tempPos = new PVector(x, y, z);
        accel = new PVector(0, 0, 0);
    }

    public Point(PVector vec) {
        this(vec.x, vec.y, vec.z);
    }

    public void move(PVector vec) {
        pos.add(vec);
        lastPos.add(vec);
    }

    public void adjustMass(float mod) {

        mass += mod;
        if (mass < .01f) {
            mass = .01f;
        }
    }

    public Point(float x, float y, float z, float mass) {

        pos = new PVector(x, y, z);
        lastPos = new PVector(x, y, z);
        tempPos = new PVector(x, y, z);
        this.mass = mass;
        accel = new PVector(0, 0, 0);
    }

    public float getVel() {
        PVector temp = PVector.sub(pos, lastPos);
        return temp.mag();

    }

    public void physics() {

        /*
        PVector down = pos.get();
        down.mult(-1f);
        float height = down.mag();
        down.mult(9.8f);
        down.div(height);

        down.div(FlightLifter.FRAMERATE_SQ);
        */
        PVector down = new PVector(0,-9.8f/FlightLifter.FRAMERATE_SQ,0);


        //Verlet integration

        tempPos.x = pos.x;
        tempPos.y = pos.y;
        tempPos.z = pos.z;

        pos.x = 2 * pos.x - lastPos.x + accel.x + down.x;
        pos.y = 2 * pos.y - lastPos.y + accel.y + down.y;
        pos.z = 2 * pos.z - lastPos.z + accel.z + down.z;

        lastPos.x = tempPos.x;
        lastPos.y = tempPos.y;
        lastPos.z = tempPos.z;

        /*
        
        if (height <= FlightLifter.WORLD_RADIUS) {
            float diff = FlightLifter.WORLD_RADIUS - height;
            down = pos.get();
            down.normalize();
            down.mult(diff);

            pos.add(down);
            lastPos.add(down);

        }

         */

        if (pos.y < 0){
            pos.y = -pos.y/2.f;
        }
        
        accel.mult(0);

    }

    //applied impulses should be in Newtons
    public void impulse(PVector dir) {

        //scale impulse for timestep and point mass
        dir.div(mass * FlightLifter.FRAMERATE * FlightLifter.FRAMERATE);

        accel.add(dir);

    }

    public void render(int mode) {
        GL11.glPushMatrix();

        GL11.glTranslatef(pos.x, pos.y, pos.z);

        if (selected == 1) {
            GL11.glPushMatrix();
            GL11.glScalef(.4f, .4f, .4f);
            GL11.glColor3f(1.0f, 1.0f, 0.0f);
            Draw.box();
            GL11.glPopMatrix();
        }

        GL11.glScalef(.2f, .2f, .2f);
        GL11.glColor3f(red, green, blue);

        Draw.box();

        GL11.glPopMatrix();


        GL11.glBegin(GL11.GL_LINES);
        GL11.glVertex3f(pos.x, pos.y, pos.z);
        GL11.glVertex3f(lastPos.x, lastPos.y, lastPos.z);
        GL11.glEnd();





    }

    public PVector getCentroid() {
        return pos;
    }

    public PVector getScreenSpaceCentroid() {
        float[] ret = GLProject.project(pos.x, pos.y, pos.z);
        return new PVector(ret[0], ret[1], 0);
    }

    public Point(String[] line) {
        this(Util.strToFlt(line[1]),
                Util.strToFlt(line[2]),
                Util.strToFlt(line[3]));
        mass = Util.strToFlt(line[4]);
    }

    public String pickle(Vector<Node> nodes) {
        return "P,"
                + pos.pickle() + ","
                + Float.floatToIntBits(mass)
                + "";
    }

    public boolean dependsOn(Point p) {
        return false;
    }
}
